package com.zy.reflect.oop;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;

/**
 * @Author Gong
 * @Description
 * @dATE 2021/12/20 15:01
 **/
public class demo {
    public static void main(String[] args) throws Exception {
        demo d  = new demo();
        d.testGetFieldInfo();
    }
    /**
     * 获取每个属性的访问修饰符    属性类型    属性名称
     * @throws Exception
     */
    public void testGetFieldInfo() throws Exception{
        System.out.println("---------------------------");
        Class clazz=Person.class;
        Field[] fileds=clazz.getDeclaredFields();
        for (Field field : fileds) {
            Annotation[] annotations = field.getAnnotations();
            for (int i = 0; i < annotations.length; i++) {
                Annotation annotation = annotations[i];
                System.out.println(annotation);
            }
//            System.out.println(annotations);
            //获取访问修饰符
            int i=field.getModifiers();
            String m=Modifier.toString(i);
            System.out.println("访问修饰符 ： "+i+" :::: "+m);
            //获取属性的类型
            System.out.println("数据类型 ： "+field.getType());
            //获取变量名称
            System.out.println("变量名称 ： "+field.getName());
        }
    }

    //获取对应的运行时类的属性
    public void testGetField() throws Exception{
        Class clazz=Person.class;
//1.getFields() 只能获取到运行时类中声明为public的属性
        Field[] fileds= clazz.getFields();
        for (Field field : fileds) {
            System.out.println(field);
        }
        System.out.println("---------------------------");
//2.getDeclaredFields() ： 获取运行时类声明的所有的属性
        fileds=clazz.getDeclaredFields();
        for (Field field : fileds) {
            System.out.println(field);
        }
    }

    //获取对应的运行时类的方法
    public void testGetMethod() throws Exception{
        Class clazz=Person.class;
        //1.getMethods()获取运行时类及其父类声明的所有的public修饰的方法
        Method[]method=clazz.getMethods();
        for (Method method2 : method) {
            System.out.println(method2);
        }
        System.out.println("---------------------------------");
        //2.getDeclaredMethods()获取运行时类本身声明的所有的的方法
        method=clazz.getDeclaredMethods();
        for (Method method2 : method) {
            System.out.println(method2);
        }
    }
    public void testGetMethodAllInfo() throws Exception{
        Class clazz=Person.class;
        Method[] method=clazz.getDeclaredMethods();
        for (Method method2 : method) {
            System.out.println("注解：");
            Annotation [] ann=method2.getAnnotations();
            for (Annotation annotation : ann) {
                System.out.print(annotation+"\t  --");
            }
            System.out.println();
            System.out.println("访问修饰符："+method2.getModifiers()+":"+ Modifier.toString(method2.getModifiers()));
            System.out.println("方法名称:"+method2.getName());
            System.out.println("返回值类型："+method2.getReturnType());
            System.out.print("形参列表：");
            Class [] types= method2.getParameterTypes();
            for (Class class1 : types) {
                System.out.print(class1.getName()+"\t ");
            }
            System.out.println();
            System.out.print("异常类型：");
            Class [] exceptions=method2.getExceptionTypes();
            for (Class class1 : exceptions) {
                System.out.print(class1+"\t");
            }
            System.out.println();
        }
    }


    // 2.获取带泛型的父类
    public void test2() throws Exception {
        Class clazz = Person.class;
        Type type = clazz.getGenericSuperclass();
        //com.zy.reflect.oop.Creature<java.lang.String>
        System.out.println(type);

    }

    // 1.获取运行时类的父类

    public void test1() throws Exception {
        Class clazz = Person.class;
        Class parent = clazz.getSuperclass();
        //class com.zy.reflect.oop.Creature
        System.out.println(parent);
    }
    // 4.获取实现的接口

    public void test4() throws Exception {
        Class clazz = Person.class;
        Class[] infaces = clazz.getInterfaces();
//        interface java.lang.Comparable
//        interface com.zy.reflect.oop.MyInterface
        for (Class class1 : infaces) {
            System.out.println(class1);
        }
    }
    // 3.获取父类的泛型

    public void test3() throws Exception {
        Class clazz = Person.class;
        Type type = clazz.getGenericSuperclass();
// 强转成子接口
        ParameterizedType param = (ParameterizedType) type;
//        获取实际的泛型类型参数数组：
        Type[] types = param.getActualTypeArguments();
// 向下转型
        //java.lang.String
        System.out.println(((Class) types[0]).getName());
    }
    // 6.获取注解

    public void test6() throws Exception {
        Class clazz = Person.class;
        //@com.zy.reflect.oop.MyAnnotatin(value=value=atwyl)
        Annotation[] anns = clazz.getAnnotations();
        for (Annotation annotation : anns) {
            System.out.println(annotation);
        }
    }

    // 5.获取所在包

    public void test5() throws Exception {
        Class clazz = Person.class;
//        类所在的包    Package getPackage()
        Package packages = clazz.getPackage();
        //package com.zy.reflect.oop
        System.out.println(packages);
    }

}
